/*
*
==============================================================================
*  Name        : 
*  Part of     : Omen Game Engine - DirectX 10 Plugin
*  Description : 
*  Version     : 1.0
*
*  Copyright (c) 2013 Lauri Kortevaara.
* 
==============================================================================
*/

#pragma once

/// Omen Headers
#include <IOmenShader.h>

#include "Config.h"

#include <d3d10.h>
#include <D3DX10math.h>

namespace Omen
{
    class DIRECTX_10_PLUGIN_API BasicShader : public Omen::IShader
    {
        #define UUID_DIRECTX_10_BASICSHADER "DC1E50F0-A213-44F1-A8D0-2F3AF86BD389"

    public:
        virtual Omen_GUID classId() const { return OMEN_UUID(UUID_DIRECTX_10_BASICSHADER); }  //

        BasicShader( ID3D10Device* pDevice, 
                    const std::wstring& vertexShaderFileName,
                    const std::wstring& pixelShaderFileName,
                    const std::wstring& geometryShaderFileName );

        virtual bool isValid();

        ID3D10InputLayout* getInputLayout() const;
        void initializeShader();

        ID3D10Effect*   effect() const;
        ID3D10EffectTechnique*   technique() const;

        void setTexture( const std::wstring& strTexturePath );

        ID3D10ShaderResourceView*&           textureResourceView();
        ID3D10EffectMatrixVariable*         worldMatrix();
        ID3D10EffectMatrixVariable*         viewMatrix();
        ID3D10EffectMatrixVariable*         projectionMatrix();
        ID3D10EffectVectorVariable*         meshColor();
        ID3D10EffectShaderResourceVariable* textureVariable();
        ID3D10EffectVectorVariable*            eyeVariable();

        // Shader Omen::IRenderable
        virtual void render(const Omen::IRenderer *);

         /// Vertex Shader
        virtual void setVertexShaderPtr( void* pShader );
        virtual void* getVertexShaderPtr();

        virtual void setVertexShaderSource( wchar_t* pSource, unsigned long size );
        virtual void getVertexShaderSource( wchar_t* pSource, unsigned long maxSize );

        /// Pixel Shader
        virtual void setPixelShaderPtr( void* pShader );
        virtual void* getPixelShaderPtr();

        virtual void setPixelShaderSource( wchar_t* pSource, unsigned long size );
        virtual void getPixelShaderSource( wchar_t* pSource, unsigned long maxSize );

        /// Geometry Shader
        virtual void setGeometryShaderPtr( void* pShader );
        virtual void* getGeometryShaderPtr();

        virtual void setGeometryShaderSource( wchar_t* pSource, unsigned long size );
        virtual void getGeometryShaderSource( wchar_t* pSource, unsigned long maxSize );


    protected:
        HRESULT CreateInputLayoutDescFromVertexShaderSignature( ID3DBlob* pShaderBlob, ID3D10Device* pD3DDevice, ID3D10InputLayout** pInputLayout );
    private:
        ID3D10Device*       m_pDevice;

        #pragma warning(disable:4251) // Disable warning about private member variable needs to have dll-interface to be used by clients of class 'this'
        std::wstring        m_shaderFileName;

        std::wstring        m_shaderSource;
        

        ID3D10Effect            *m_pShaderEffect;
        ID3D10EffectTechnique   *m_pShaderTechnique;

        ID3D10InputLayout*      m_pVertexShaderInputLayout;
        ID3D10Blob*             m_pBlobShaderErrors;

        // Matrices
        D3DXMATRIX                          m_World;
        D3DXMATRIX                          m_View;
        D3DXMATRIX                          m_Projection;


        // Shader resources and variables
        ID3D10ShaderResourceView*           m_pTextureRV;
        ID3D10EffectMatrixVariable*         m_pWorldVariable;
        ID3D10EffectMatrixVariable*         m_pViewVariable;
        ID3D10EffectMatrixVariable*         m_pProjectionVariable;
        ID3D10EffectVectorVariable*         m_pMeshColorVariable;
        ID3D10EffectShaderResourceVariable* m_pTextureVariable;
        ID3D10EffectVectorVariable*            m_pEyeVariable;

        #pragma warning(default:4251) // Set Defeault state of warning about private member variable needs to have dll-interface to be used by clients of class 'this'
    };
}